﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using Microsoft.MediaCenter.UI;
using System.Diagnostics;
using MyMoviesBrowserLibrary;

namespace MyMoviesBrowser
{
    public class EpisodeGallery : GalleryPage
    {
        private TVEpisode currentEpisode;
        public TVEpisode CurrentEpisode
        {
            get { return currentEpisode; }
            set
            {
                if (currentEpisode != value)
                {
                    currentEpisode = value;
                    FirePropertyChanged("CurrentEpisode");
                }
            }
        }

        public Image BackgroundImage
        {
            get
            {
                string imageLocation = Path.Combine(CurrentSeason.Series.FolderLocation, "fanart.jpg");
                if (File.Exists(imageLocation))
                    return new Image("file://" + imageLocation);
                else
                    return new Image("resx://MyMoviesBrowser/MyMoviesBrowser.Resources/clear");
            }
        }
        public bool ShowBackgroundImage
        {
            get
            {
                string imageLocation = Path.Combine(CurrentSeason.Series.FolderLocation, "fanart.jpg");
                return File.Exists(imageLocation);
            }
        }

        public Season CurrentSeason { get; set; }
        public List<TVEpisode> Episodes { get; set; }

        private TVManagerBusinessLayer bl = new TVManagerBusinessLayer();

        public EpisodeGallery()
        { }

        public EpisodeGallery(Season season)
        {
            Episodes = new List<TVEpisode>();
            ItemSize = GalleryItemSize.Small;
            Description = string.Format("{0} {1}",season.Series.SeriesName, season.Name);

            
            CurrentSeason = season;
            var q = season.Episodes.Where(e=>!string.IsNullOrEmpty(e.FileLocation)).OrderBy(e=>e.EpisodeNumber.Value).ToList();
            foreach (Episode ep in q)
            {
                Episodes.Add(new TVEpisode(ep));
            }

            VirtualList galleryList = new VirtualList(this, null);
            galleryList.EnableSlowDataRequests = true;
            galleryList.RequestSlowDataHandler = new RequestSlowDataHandler(CompleteGalleryItem);
            Content = galleryList;

            CreateGalleryFilters();
        }

        private void CreateGalleryFilters()
        {
            //
            // Put together a list of filters on the content.
            //

            ArrayListDataSet list = new ArrayListDataSet(this);

            // Create the unfiltered "All" filter
            ModelItem filter = new Filter(this, "Episode", 0);
            list.Add(filter);

            filter = new Filter(this, Resources.FilterBy_NotWatched, 1);
            list.Add(filter);

            filter = new Filter(this, Resources.GroupBy_LastAdded, 2);
            list.Add(filter);            

            filter = new Filter(this, Resources.FilterBy_Rating, 3);
            list.Add(filter);

            Choice filters = new Choice(this, null, list);
            filters.Chosen = (ModelItem)list[0];

            //
            // Hook up the "filter changed" event so that we can apply the
            // active filter to our gallery.
            //
            // As soon as this Filters list is set, we will get an OnActiveFilterChanged
            // event which will cause us to populate the gallery.
            //

            ActiveFilterChanged += delegate(object sender, EventArgs e)
            {
                EpisodeGallery galleryPage = (EpisodeGallery)sender;
                Filter activeFilter = (Filter)galleryPage.Filters.Chosen;
                FilterContent(galleryPage, activeFilter.FilterId);
            };
            Filters = filters;
        }

        private void FilterContent(EpisodeGallery page, int filterId)
        {
            Content.Clear();

            //
            // Populate the list with items according to the filter.
            //
            switch (filterId)
            {
                case 1:
                    foreach (TVEpisode episode in Episodes.Where(e => !e.Episode.Watched))
                        this.Content.Add(CreateGalleryItem(episode, "", false));
                    break;
                case 2:
                    var r3 = Episodes.OrderByDescending(m => m.Episode.DateAdded.Date).ThenBy(m => m.Episode.EpisodeNumber).GroupBy(t => t.Episode.DateAdded.Date);
                    foreach (var result in r3)
                    {
                        bool first = true;
                        foreach (var m in result)
                        {
                            page.Content.Add(CreateGalleryItem(m, m.Episode.DateAdded.ToString("MMM d, yyyy"), first));
                            first = false;
                        }
                    }
                    break;
                case 3:
                    var r4 = Episodes.OrderByDescending(m => m.Episode.Rating).ThenBy(m => m.Episode.EpisodeNumber).GroupBy(t => t.Episode.Rating);
                    foreach (var result in r4)
                    {
                        bool first = true;
                        foreach (var m in result)
                        {
                            page.Content.Add(CreateGalleryItem(m, m.Episode.Rating.ToString(), first));
                            first = false;
                        }
                    }
                    break;
                
                default:
                    foreach (TVEpisode episode in Episodes)
                        this.Content.Add(CreateGalleryItem(episode, "", false));
                    break;
            }
        }

        private ThumbnailCommand CreateGalleryItem(TVEpisode episodeData, string description, bool isHeading)
        {
            ThumbnailCommand item = new ThumbnailCommand(this);
            item.Description = episodeData.Episode.EpisodeNameAndNumber;
            item.Data = episodeData;
            item.ShowHeading = isHeading;
            item.Metadata = description;

            item.Invoked += delegate(object sender, EventArgs args)
            {
                ThumbnailCommand galleryItem = (ThumbnailCommand)sender;
                TVEpisode episode = (TVEpisode)galleryItem.Data;
                MediaFile mediaFile = new MediaFile() { FileName = Path.GetFileName(episode.Episode.FileLocation), Path = episode.Episode.FileLocation };
                episode.Episode.Watched = true;
                bl.SetEpisodeWatchedStatus(episode.Episode);
                Application.Current.PlayMedia(mediaFile);
            };

            item.OnFocus += delegate(object sender, EventArgs args)
            {
                ThumbnailCommand galleryItem = (ThumbnailCommand)sender;

                EpisodeGallery page = (EpisodeGallery)galleryItem.Owner;
                page.CurrentEpisode = (TVEpisode)galleryItem.Data;
            };

            return item;
        }

        #region slowdatahandlers
        /// <summary>
        /// Finishes any slow data for a gallery item.
        /// </summary>
        protected void CompleteGalleryItem(VirtualList list, int index)
        {
            ThumbnailCommand item = (ThumbnailCommand)list[index];
            CompleteGalleryItem(item, (TVEpisode)item.Data);
        }

        /// <summary>
        /// Finishes any slow data for a gallery item.
        /// </summary>
        protected void CompleteGalleryItem(ThumbnailCommand item, TVEpisode episodeData)
        {
            string imageName = "file://" + episodeData.Episode.ImageFileLocation;
            item.Image = LoadImage(imageName);
        }
        #endregion

        public override int JumpTo(string searchText)
        {
            searchText = searchText.ToLower();
            List<TVEpisode> temp = Content.Cast<ThumbnailCommand>().Select(t => t.Data).Cast<TVEpisode>().ToList();
            List<TVEpisode> temp2 = new List<TVEpisode>();

            int num = 0;
            if(int.TryParse(searchText, out num))
            {
                TVEpisode episode = temp.FirstOrDefault(e => e.Episode.EpisodeNumber == num);
                if (episode != null)
                    return temp.IndexOf(episode);
                else
                    return -1;
            }
            else
            {
                do
                {
                    temp2 = (from m in temp
                             where m.Episode.EpisodeName.ToLower().StartsWith(searchText)
                             select m).ToList();
                    if (searchText.Length > 0)
                        searchText = searchText.Substring(0, searchText.Length - 1);
                } while (temp2.Count == 0 && searchText.Length > 0);

                if (temp2.Count > 0)
                {
                    int i = temp.IndexOf(temp2.First());
                    return i;
                }
                return -1;
            }

        }
    }
}
